<?php
namespace app\index\controller;
use app\index\Controller;
use think\Db;
use think\Error;
use think\Request;
use think\Validate;

/**
 * @title 试题（模块11）
 * @description 接口说明
 * @group 试题
 * @header name:model_id   default:05 desc:模块id
 * @groupremark 已使用错误码：1110001 1110002 1110003 1110004 1110005
 */
class Paper extends Controller
{

    /**
     * @title 生成试卷
     * @description 接口说明
     * @author 李锐志
     * @url /index/paper/create
     * @param name:token type:string require:1  other: desc:token
     * @param name:user_id type:int require:1  other: desc:user_id
     * @param name:rank_id type:int require:1  other: desc:rank_id
     * @method ~
     * @return error_id: 1110001 校验失败
     * @return error_id: 1110002 司机缺少等级
     * @return paper_type_id:试卷类型id
     * @return user_paper_id:用户试卷id
     * @return judge_num:判断题数量
     * @return radio_num:单选题数量
     * @return multi_num:多选题数量
     * @return judge:所有判断题@!
     * @judge id:题目id title:题目 type:题目类型 rank_id:司机等级 analysis:解析 content:内容 item:选项@!
     * @item item_content:选项内容 symbol:选项符号
     */
    public function create()
    {

        $data = input();
        logs('paperData',$data);
        //验证规则
        $validate = new Validate([
            ['token', 'require', '缺少token'],
            ['user_id', 'require', '未指定用户'],
        ]);

        //验证数据
        if (!$validate->check($data)) {
            $msg['error_id'] = "1110001";
            $msg['message'] = $validate->getError();
            return $this->error($msg);
        }
        //根据用户id找到该用户的司机等级
        $rank_id=$data['rank_id'];
        if ($rank_id != null) {
            //根据司机等级找到相对应的试卷类型
            $paper = Db::name('paper_type')->where('rank_id', $rank_id)->find();
            //返回试卷类型的id
            $msg['paper_type_id'] = $paper['id'];
            $judge_num = Db::name('paper_type')->where('id', $paper['id'])->value('judge_num');
            $msg['judge_num'] = $judge_num;
            $radio_num = Db::name('paper_type')->where('id', $paper['id'])->value('radio_num');
            $msg['radio_num'] = $radio_num;
            $multi_num = Db::name('paper_type')->where('id', $paper['id'])->value('multi_num');
            $msg['multi_num'] = $multi_num;
            $judge = Db::name('paper_questions')->where('type', 'judge')->where('rank_id', $rank_id)->select();
            $radio = Db::name('paper_questions')->where('type', 'radio')->where('rank_id', $rank_id)->select();
            $multi = Db::name('paper_questions')->where('type', 'multi')->where('rank_id', $rank_id)->select();

            //生成判断题目
            if($judge_num>0&&$judge_num<=count($judge)){
                $judge_key = array_rand($judge, $judge_num);
                if(!is_array($judge_key)){
                  $judge_key=[$judge_key];
                }
                for ($i = 0; $i < count($judge_key); $i++) {
                    $judge_re[$i] = $judge[$judge_key[$i]];
                    //查询题目选项并保存
                    $judge_item[$i] = Db::name('paper_questions_item')->field('item_content,symbol')->where('question_id', $judge[$judge_key[$i]]['id'])->select();
                    $judge_re[$i]['item'] = $judge_item[$i];
                }
            }else{
                $msg['error_id'] = "1110002";
                $msg['message'] = $paper['title'].'判断题题量不足';
                return $this->error($msg);
            }

            //生成单选题目
            if($radio_num>0&&$radio_num<=count($radio)){
                $radio_key = array_rand($radio, $radio_num);
                if(!is_array($radio_key)){
                  $radio_key=[$radio_key];
                }
                for ($i = 0; $i < count($radio_key); $i++) {
                    $radio_re[$i] = $radio[$radio_key[$i]];
                    $radio_item[$i] = Db::name('paper_questions_item')->field('item_content,symbol')->where('question_id', $radio[$radio_key[$i]]['id'])->select();
                    $radio_re[$i]['item'] = $radio_item[$i];
                }
            }else{
                $msg['error_id'] = "1110002";
                $msg['message'] =$paper['title'].'单选题题量不足';
                return $this->error($msg);
            }

            //生成多选题目
            if($radio_num>0&&$multi_num<=count($multi)){
                $multi_key = array_rand($multi, $multi_num);
                if(!is_array($multi_key)){
                  $multi_key=[$multi_key];
                }
                for ($i = 0; $i < count($multi_key); $i++) {
                    $multi_re[$i] = $multi[$multi_key[$i]];
                    $multi_item[$i] = Db::name('paper_questions_item')->field('item_content,symbol')->where('question_id', $multi[$multi_key[$i]]['id'])->select();
                    $multi_re[$i]['item'] = $multi_item[$i];
                }

            }else{
                $msg['error_id'] = "1110002";
                $msg['message'] = $paper['title'].'多选题题量不足';
                return $this->error($msg);
            }

            $msg['judge'] = $judge_re;
            $msg['radio'] = $radio_re;
            $msg['multi'] = $multi_re;

            //生成试卷题目
            $paper_list = array_merge((array)$judge_re, (array)$radio_re, (array)$multi_re);

            //向user_paper表中插入数据
            $insert_user_paper['user_id'] = $data['user_id'];
            $insert_user_paper['paper_type_id'] = $paper['id'];
            $insert_user_paper['rank_id'] = $rank_id;
            $user_paper = Db::name('user_paper')->where('user_id', $data['user_id'])->where('paper_type_id', $paper['id'])->find();
            if ($user_paper == null) {
                Db::name('user_paper')->insert($insert_user_paper);
            }

            //每次重新访问接口时，user_paper_querstions表中的对应数据需要更新
            $user_paper_new = Db::name('user_paper')->where('user_id', $data['user_id'])->where('paper_type_id', $paper['id'])->find();
            //返回试卷的id
            $msg['user_paper_id'] = $user_paper_new['id'];
            $result = Db::name('user_paper_querstions')->where('user_paper_id', $user_paper_new['id'])->where('user_id', $data['user_id'])->select();
            if ($result != null) {
                Db::name('user_paper_querstions')->where('user_paper_id', $user_paper_new['id'])->where('user_id', $data['user_id'])->delete();
            }

            //向user_paper_querstions表中插入数据
            for ($i = 0; $i < count($paper_list); $i++) {
                $insert_user_paper_querstions['user_paper_id'] = $user_paper_new['id'];
                $insert_user_paper_querstions['user_id'] = $user_paper_new['user_id'];
                $insert_user_paper_querstions['paper_questions_id'] = $paper_list[$i]['id'];
                $item = Db::name('paper_questions_item')->where('question_id', $paper_list[$i]['id'])->select();
                for ($j = 0; $j < count($item); $j++) {
                    if ($item[$j]['value'] == '1')
                        $insert_user_paper_querstions['answer'] .= $item[$j]['symbol'];
                }

                //插入数据
                Db::name('user_paper_querstions')->insert($insert_user_paper_querstions);
                //当题目没有答案时，会沿用上一题的答案，为了避免错误，每插入一条数据，answer就清空
                $insert_user_paper_querstions['answer'] = null;
            }

            if ($paper != null) {
                return $this->success($msg);
            }
        } else {
            $msg['error_id'] = "1110002";
            $msg['message'] = '该司机没有等级';
            return $this->error($msg);
        }
    }

    /**
     * @title 提交试卷
     * @description 接口说明
     * @author 李锐志
     * @url /index/paper/submit_paper
     * @param name:token type:string require:1  other: desc:token
     * @param name:user_id type:int require:1  other: desc:user_id
     * @param name:paper_type_id type:int require:1  other: desc:试卷类型id
     * @param name:user_paper_id type:int require:1  other: desc:试卷id
     * @param name:questions type:int require:1  other: desc:questions
     * @method ~
     * @return error_id: 1110003 已考过阶段测试或已提交过申请
     * @return tip:提交试卷表单中，单选和判断的name="questions[题目id]",多选的name="questions[题目id][]"
     */
    public function submit_paper(Request $request)
    {

        //获取数据post数据
        $result = input();
        //验证规则
        $validate = new Validate([
            ['token', 'require', '缺少token'],
            ['user_id', 'require', '缺少user_id'],
            ['paper_type_id', 'require', '缺少paper_type_id'],
            ['user_paper_id', 'require', '缺少user_paper_id'],
            ['questions', 'require', '缺少questions'],
        ]);

        //验证数据
        if (!$validate->check($result)) {
            $msg['error_id'] = "1110001";
            $msg['message'] = $validate->getError();
            return $this->error($msg);
        }

        $user_id = $result['user_id'];
        $paper_type_id = $result['paper_type_id'];
        $user_paper_id = $result['user_paper_id'];
        $questions = $result['questions'];

        //将答案和分数写入数据表中
        $this->user_answer($questions, $user_paper_id, $paper_type_id);

        //分数求和
        $sum = Db::name('user_paper_querstions')
            ->where('user_paper_id', $user_paper_id)
            ->sum('user_score');
        //  查询司机蛋卷的所有答案
        $driverAnswer = Db::name('user_paper_querstions')
            ->where('user_paper_id', $user_paper_id)
            ->order('id','asc')
            ->select();;
            logs('driverAnswer',$driverAnswer);
        // 求出打错的题目
        $radio = []; // 单选题
        $trueOrFalse = []; // 判断题
        $multiple = []; // 多选题
        if ($driverAnswer){
            // 查找考试等级信息
            $rankId= Db::name('paper_questions')->where('id',$driverAnswer[0]['paper_questions_id'])->value('rank_id');
            $driverRateinfo = Db::name('paper_type')->where('rank_id',$rankId)->find(); // 这是等级的考试
            $questions = []; // 试题
            // 先分成判断题
            if ($driverRateinfo['judge_num']){
                for ($i = 0;$i < $driverRateinfo['judge_num']; $i++){
                    $questions['judge'][] = $driverAnswer[$i];
                }
            }
            // 单选题
            if ($driverRateinfo['radio_num']){
                $num = $driverRateinfo['radio_num'] + $driverRateinfo['judge_num'];
                for ($j = $driverRateinfo['judge_num']; $j < $num; $j++){
                    $questions['radio'][] = $driverAnswer[$j];
                }
            }
            // 多选题
            if ($driverRateinfo['multi_num']){
                $num = $driverRateinfo['radio_num'] + $driverRateinfo['judge_num'] + $driverRateinfo['multi_num'];
                $radio_num = $driverRateinfo['radio_num'] + $driverRateinfo['judge_num'];
                for ($k = $radio_num; $k < $num; $k++){
                    $questions['multi'][] = $driverAnswer[$k];
                }
            }
            logs('question', $questions);
            if ($questions['judge']){ // 判断题
                static $pan = 1;
                foreach ($questions['judge'] as $index08 => $question08) {
                    if ($question08['user_answer'] != $question08['answer']){
                        $trueOrFalse[] = $pan; // 把题号添加
                    }
                    $pan++;
                }
                unset($pan);
            }
            if ($questions['radio']){ // 单选题
                static $dan = 1;
                foreach ($questions['radio'] as $index09 => $question09) {
                    if ($question09['user_answer'] != $question09['answer']){
                        $radio[] = $dan; // 把题号添加
                    }
                    $dan++;
                }
                unset($dan);
            }
            if ($questions['multi']){ // 多选题
                static $duo = 1;
                foreach ($questions['multi'] as $index10 => $question10) {
                    if ($question10['user_answer'] != $question10['answer']){
                        $multiple[] = $duo; // 把题号添加
                    }
                    $duo++;
                }
                unset($duo);
            }
        }
        logs('question', $trueOrFalse);
        logs('question', $radio);
        logs('question', $multiple);
        //把总分写入user_paper表中
        Db::name('user_paper')
            ->where('id', $user_paper_id)
            ->setField('score', $sum);

        //获取试卷对应的司机等级
        $rank_id = Db::name('paper_type')->where('id', $paper_type_id)->value('rank_id');

        //获取升级标准
        $driver_rank = Db::name('driver_rank')
            ->field('min_score,order_num')
            ->where('id', $rank_id)
            ->find();

        //符合标准的用户自动提交升级申请
        $order_num = Db::name('driver')->where('user_id', $user_id)->value('order_num');
        $score = Db::name('user_paper')->where('paper_type_id', $paper_type_id)
            ->where('user_id', $user_id)->value('score');
        $promptMessage = ''; // 打错的题是信息
        if (!empty($trueOrFalse)){
            $trueOrFalse = implode(',',$trueOrFalse);
            $promptMessage .= "判断题错误的题号为:{$trueOrFalse},<br><br>";
        }
        if (!empty($radio) && is_array($radio)){
            $radioStr = implode(',', $radio);
            $promptMessage .= "单选题错误的题号为:{$radioStr},<br><br>";
        }
        if (!empty($multiple)){
            $multiple = implode(',',$multiple);
            $promptMessage .= "多选题错误的题号为{$multiple},<br><br>";
        }
        if ($score >= $driver_rank['min_score']) {
            Db::name('user_paper')->where('paper_type_id', $paper_type_id)->where('user_id', $user_id)->update(array('ispass'=>true));
            if($order_num >= $driver_rank['order_num'] ){
                $driver = Db::name('driver_rank_apply')
                    ->where('user_paper_id', $user_paper_id)
                    ->where('user_id', $user_id)->find();
                if ($driver == null) {
                    Db::name('driver_rank_apply')->insert([
                        'user_id' => $user_id,
                        'create_time' => time(),
                        'rank_id' => $rank_id,
                        'score' => $sum,
                        'user_paper_id' => $user_paper_id,
                    ]);
                    $msg['message'] = '考试通过，并提交等级考核申请';
                    $msg['score'] = $sum;
                    $msg['ispass'] = 1;
                    return $this->success($msg);
                } else {
                    $msg['error_id'] = "1110003";
                    $msg['message'] = '考试通过，已经提交过等级考核申请';

                    $msg['ispass'] = 1;
                    return $this->error($msg);
                }
            }else{
                $msg['error_id'] = "1110004";
                $msg['message'] = "考试通过，需要完成相应的订单量才能进行等级考核申请";
                $msg['ispass'] = 1;
                return $this->error($msg);
            }
        }else{
            $msg['error_id'] = "1110005";
            $msg['message'] = "您的考试成绩是:{$sum}分,<br><br>{$promptMessage}考试未通过，请重新考试";
//            $msg['message'] = "考试未通过，请重新考试";
            $msg['score'] = $sum;
            $msg['ispass'] = 0;
            return $this->success($msg);
        }
    }

    private function user_answer($questions, $user_paper_id, $paper_type_id)
    {

        //获取每种题型的分数
        $score = Db::name('paper_type')->field('pre_judge_score,pre_radio_score,pre_multi_score')->where('id', $paper_type_id)->find();

        //确认题目循环写入答案
        foreach ($questions as $k => $v) {
            //判断是不是多选题，是多选把答案拼接
            if (is_array($v)) {
                $value = '';
                for ($i = 0; $i < count($v); $i++) {
                    $value .= $v[$i];
                }
                //写入用户答案
                Db::name('user_paper_querstions')
                    ->where('paper_questions_id', $k)
                    ->where('user_paper_id', $user_paper_id)
                    ->setField('user_answer', $value);

                //获取题目类型
                $type = Db::name('paper_questions')
                    ->where('id', $k)
                    ->value('type');

                //获取标准答案和用户答案
                $result = Db::name('user_paper_querstions')
                    ->field('answer,user_answer')
                    ->where('paper_questions_id', $k)
                    ->where('user_paper_id', $user_paper_id)
                    ->find();

                //清空当前分数
                Db::name('user_paper_querstions')
                    ->where('paper_questions_id', $k)
                    ->where('user_paper_id', $user_paper_id)
                    ->setField('user_score', '');

                //判断答案是否正确
                if ($result['answer'] == $result['user_answer']) {
                    Db::name('user_paper_querstions')
                        ->where('paper_questions_id', $k)
                        ->where('user_paper_id', $user_paper_id)
                        ->setField('user_score', $score['pre_' . $type . '_score']);
                }

            } else {
                //写入用户答案
                Db::name('user_paper_querstions')
                    ->where('paper_questions_id', $k)
                    ->where('user_paper_id', $user_paper_id)
                    ->setField('user_answer', $v);

                //获取题目类型
                $type = Db::name('paper_questions')
                    ->where('id', $k)
                    ->value('type');

                //获取标准答案和用户答案
                $result = Db::name('user_paper_querstions')
                    ->field('answer,user_answer')
                    ->where('paper_questions_id', $k)
                    ->where('user_paper_id', $user_paper_id)
                    ->find();

                //清空当前分数
                Db::name('user_paper_querstions')
                    ->where('paper_questions_id', $k)
                    ->where('user_paper_id', $user_paper_id)
                    ->setField('user_score', '');

                //判断答案是否正确
                if ($result['answer'] == $result['user_answer']) {
                    Db::name('user_paper_querstions')
                        ->where('paper_questions_id', $k)
                        ->where('user_paper_id', $user_paper_id)
                        ->setField('user_score', $score['pre_' . $type . '_score']);
                }
            }
        }
    }

    /**
     * @title 验证试题量
     * @description 检查试题是否充足
     * @author 邓汉炜
     * @url /index/paper/verifyTest
     * @param name:token type:string require:1  other: desc:token
     * @param name:user_id type:int require:1  other: desc:user_id
     * @param name:rank_id type:int require:1  other: desc:rank_id
     * @method ~
     * @return error_id: 1110001 校验失败
     * @return error_id: 1110002 不存在该等级信息
     * @return error_id: 1110003 题量不足
     * @return error_id: 1110004 试题没有答案
     * @return paper_type_id:试卷类型id
     * @return user_paper_id:用户试卷id
     * @return judge_num:判断题数量
     * @return radio_num:单选题数量
     * @return multi_num:多选题数量
     * @return judge:所有判断题@!
     * @judge id:题目id title:题目 type:题目类型 rank_id:司机等级 analysis:解析 content:内容 item:选项@!
     * @item item_content:选项内容 symbol:选项符号
     */
    public function verifyTest()
    {
        $data = input();
        // 验证数据
        $rule = [
            'token'=> 'require',
            'user_id'=> 'require',
            'rank_id'=> 'require',
        ];
        $messge = [
            'token.require' => '缺少token',
            'user_id.require' => '缺少用户参数',
            'rank_id.require' => '缺少用户等级',
        ];
        $validate = new Validate($rule,$messge);
        $result = $validate->check($data);
        if (!$result){
            $msg['error_id'] = 1110001;
            $msg['message'] = $validate->getError();
            return $this->error($msg);
        }
        // 根据等级查找相对应的等级信息
        $driverLevel = Db::name('paper_type')->where('rank_id',$data['rank_id'])->find();
        $driverTitle = $driverLevel['title'];
        if (!$driverLevel){
            $msg['error_id'] = 1110002;
            $msg['message'] = '不存在该等级信息';
            return $this->error($msg);
        }
        // 判断该等级到该等级的试题量是否充足
        // 判断题
        $judge = Db::name('paper_questions')->where('type', 'judge')->where('rank_id', $data['rank_id'])->select();
        if($driverLevel['judge_num'] > 0 && count($judge) >= $driverLevel['judge_num']){
            // 判断试题的答案是否充足
            foreach ($judge as $index => $item) {
                $find = Db::name('paper_questions_item')->where('question_id',$item['id'])->find();
                if (!$find){
                    $msg['message'] = "{$driverTitle}的第{$item['id']}判断题没有设置答案";
                    $msg['error_id'] = 1110004;
                    return $this->error($msg);
                }
            }
        }else{
            $msg['error_id'] = 1110003;
            $msg['message'] = "请联系管理员添加充足{$driverTitle}的判断题量";
            return $this->error($msg);
        }
        // 单选题
        $radio = Db::name('paper_questions')->where('type', 'radio')->where('rank_id', $data['rank_id'])->select();
        if($driverLevel['radio_num'] > 0 && count($radio) >= $driverLevel['radio_num']){
            // 判断试题的答案是否充足
            foreach ($radio as $index01 => $item01) {
                $find = Db::name('paper_questions_item')->where('question_id',$item01['id'])->find();
                if (!$find){
                    $msg['message'] = "{$driverTitle}的第{$item01['id']}单选题没有设置答案";
                    $msg['error_id'] = 1110004;
                    return $this->error($msg);
                }
            }
        }else{
            $msg['error_id'] = 1110003;
            $msg['message'] = "请联系管理员添加充足{$driverTitle}的单选题题量";
            return $this->error($msg);
        }
        // 多选题量
        $multi = Db::name('paper_questions')->where('type', 'multi')->where('rank_id', $data['rank_id'])->select();
        if($driverLevel['radio_num'] > 0 && count($multi) >= $driverLevel['radio_num']){
            // 判断试题的答案是否充足
            foreach ($multi as $index02 => $item02) {
                $find = Db::name('paper_questions_item')->where('question_id',$item02['id'])->find();
                if (!$find){
                    $msg['message'] = "{$driverTitle}的第{$item02['id']}多选题没有设置答案";
                    $msg['error_id'] = 1110004;
                    return $this->error($msg);
                }
            }
        }else{
            $msg['error_id'] = 1110003;
            $msg['message'] = "请联系管理员添加充足{$driverTitle}的多选题量";
            return $this->error($msg);
        }
        // 试题充足
        $msg['message'] = '试题量充足';
        return $this->success($msg);
    }

    /**
     * 记录考试的日志
     * /index/paper/addLogs
     */
    public function addLogs()
    {
        $data = input();
        logs('addPaperLog',$data);
        $msg['message'] = '添加成功';
        return $this->success($msg);
    }
}
